package output;

import java.util.List;
import java.util.Locale;

import corpus.SentPolarityCorpus;
import forum.ForumPost;
import forum.ForumSentence;

public class PolarityEvaluator implements Output {
	private SentPolarityCorpus correct;

	public PolarityEvaluator(SentPolarityCorpus correct) {
		this.correct = correct;
	}

	private double fmeasure(double beta, double precision, double recall) {
		return (1 + Math.pow(beta, 2)) * (precision * recall)
				/ (Math.pow(beta, 2) * precision + recall);
	}

	private double precision(int tp, int fp) {
		return (double) tp / (double) (tp + fp);
	}

	private double recall(int tp, int fn) {
		return (double) tp / (double) (tp + fn);
	}

	private void print(double recall, double precision) {
		System.out.printf(Locale.ENGLISH, "%1.3f\t%1.3f", recall, precision);
	}
	
	@Override
	public void outputThread(List<ForumPost> f) throws Exception {
		int[][] cm = new int[3][3];

		for (ForumPost fp : f) {
			for (ForumSentence fs : fp.getSentences()) {
				String emotion = correct.getCorpus().get(fs.getText());
				String guess = fs.getEmotion();
				int row = 0;
				int col = 0;
				if (guess.equals("neu"))
					col = 0;
				else if (guess.equals("pos"))
					col = 1;
				else
					col = 2;
				if (emotion.equals("neu"))
					row = 0;
				else if (emotion.equals("pos"))
					row = 1;
				else
					row = 2;
				cm[row][col]++;
			}
		}

		double neuP = precision(cm[0][0], cm[1][0] + cm[2][0]);
		double neuR = recall(cm[0][0], cm[0][1] + cm[0][2]);
		double neuF = fmeasure(1.0, neuP, neuR);

		double posP = precision(cm[1][1], cm[0][1] + cm[2][1]);
		double posR = recall(cm[1][1], cm[1][0] + cm[1][2]);
		double posF = fmeasure(1.0, posP, posR);

		double negP = precision(cm[2][2], cm[0][2] + cm[1][2]);
		double negR = recall(cm[2][2], cm[2][0] + cm[2][1]);
		double negF = fmeasure(1.0, negP, negR);

		double avgP = (neuP + posP + negP) / 3.0;
		double avgR = (neuR + posR + negR) / 3.0;

		System.out.println("Class\tP\tR\tF1");
		System.out.print("neu\t");
		print(neuP, neuR);
		System.out.printf(Locale.ENGLISH, "\t%1.3f\n", neuF);
		System.out.print("pos\t");
		print(posP, posR);
		System.out.printf(Locale.ENGLISH, "\t%1.3f\n", posF);
		System.out.print("neg\t");
		print(negP, negR);
		System.out.printf(Locale.ENGLISH, "\t%1.3f\n", negF);
		System.out.print("avg\t");
		print(avgP, avgR);
		System.out.printf(Locale.ENGLISH, "\t%1.3f\n", (neuF+posF+negF)/3.0);

		System.out.println();
		System.out.println("Confusion matrix (Actual X Predicted)");
		System.out.println("\tneu\tpos\tneg");
		System.out.println("neu\t" + cm[0][0] + "\t" + cm[0][1] + "\t"
				+ cm[0][2]);
		System.out.println("pos\t" + cm[1][0] + "\t" + cm[1][1] + "\t"
				+ cm[1][2]);
		System.out.println("neg\t" + cm[2][0] + "\t" + cm[2][1] + "\t"
				+ cm[2][2]);
	}

	public void close() {
	}
}
